package com.wys.spring.health;

import com.alibaba.druid.pool.DruidDataSource;
import com.wys.spring.health.SpringEmptyHealthIndicator;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
import org.springframework.boot.actuate.health.HealthContributor;
import org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.Map;

public class SpringDataSourceHealthContributorConfiguration extends CompositeHealthContributorConfiguration<DataSourceHealthIndicator, DataSource> {

    private static final Logger log = LoggerFactory.getLogger(SpringDataSourceHealthContributorConfiguration.class);
    private final Map<String, DataSource> dataSourceMap;

    public SpringDataSourceHealthContributorConfiguration(Map<String, DataSource> dataSourceMap) {
        this.dataSourceMap = filterDataSource(dataSourceMap);
    }

    public Map<String, DataSource> filterDataSource(Map<String, DataSource> dataSourceMap) {
        Map<String, DataSource> sourceMap = new LinkedHashMap<>();
        if (dataSourceMap != null) {
            for (Map.Entry<String, DataSource> stringDataSourceEntry : dataSourceMap.entrySet()) {
                if (stringDataSourceEntry.getValue() instanceof DruidDataSource) {
                    DruidDataSource druidDataSource = (DruidDataSource) stringDataSourceEntry.getValue();
                    if (StringUtils.isNotBlank(druidDataSource.getUrl()) && StringUtils.isNotBlank(druidDataSource.getUsername()) && StringUtils.isNotBlank(druidDataSource.getPassword()) && druidDataSource.isEnable()) {
                        sourceMap.put(stringDataSourceEntry.getKey(), stringDataSourceEntry.getValue());
                    }
                } else if (!(stringDataSourceEntry.getValue() instanceof AbstractRoutingDataSource)) {
                    try {
                        Connection connection = stringDataSourceEntry.getValue().getConnection();
                        connection.prepareStatement("SELECT 'x'").executeQuery();
                        sourceMap.put(stringDataSourceEntry.getKey(), stringDataSourceEntry.getValue());
                        connection.close();
                    } catch (SQLException e) {
                        log.warn(String.format("数据源:%s连接异常", stringDataSourceEntry.getValue()));
                    }
                }
            }
        }
        return sourceMap;
    }

    @Bean
    public HealthContributor dbHealthIndicator() {
        if (dataSourceMap == null || dataSourceMap.isEmpty()) {
            return new SpringEmptyHealthIndicator();
        }
        return createContributor(dataSourceMap);
    }


}
